home *** CD-ROM | disk | FTP | other *** search
/ Info-Mac 4 / Info_Mac IV CD-ROM (Pacific HiTech Inc.)(August 1994).iso / Sound / Utilities / ST201MusicDrivers Folder / Music Drivers / STrI.h < prev   
Text File  |  1993-11-05  |  26KB  |  632 lines

  1.  
  2. /* Header file for the SoundTrack interpreting routines: */
  3.  
  4. /* Copyright © 1991-93 by Frank Seide, Koolbarg 39d, D-22117 Hamburg */
  5.  
  6. #ifndef __SOUNDTRACKER__
  7. #define __SOUNDTRACKER__
  8.  
  9. /***** Constants: *****/
  10.  
  11. #define RESTYPE_SOUNDTRACK 'STrR'
  12. #define CHUNK_SIFF 'SIFF'                        /* FORM SIFF */
  13.  
  14. /***** Specification of the SoundTracker ('.MOD') format: *****/
  15.  
  16. #define MAXPTRS 128            /* Size of pointer table */
  17. #define MAXPTRNS MAXPTRS    /* max. number of patterns */
  18. #define AMIGAVOICES 4
  19. #define STDPATLENGTH 64
  20. /* #define AMIGA_PTRNSIZE (STDPATLENGTH * AMIGAVOICES * sizeof (struct AmigaCommand)) */
  21.  
  22. /* FileInstrData: Instrument descriptor (at the beginning of the file) */
  23.  
  24. #define MOD_INSTNAME_LEN 22
  25.  
  26. struct FileInstrData {
  27.     char filename[MOD_INSTNAME_LEN]; /* Original Amiga filename of this imstrument */
  28.     unsigned int numWords;    /* Sample length in words (!) (as used for file parsing) */
  29.     int unused : 4;                /* (unused, set to zero) */
  30.     int fineTune : 4;            /* Finetune value (-8…+7 in 16th of a semi tone) */
  31.     unsigned int volume : 8;    /* Initial volume (0…64) */
  32.     unsigned int loopWord;        /* Loopstart (in words!) (< 32768), 0 => not looping */
  33.     unsigned int loopWords;    /* Looplength (in words!) (loopWord+loopWords < 65536) */
  34.                                 /* loopWord = 0 => loopWords is the real sample */
  35.                                 /* length as used by the playing routine. Use */
  36.                                 /* numWords for parsing the file only! */
  37. };
  38.  
  39. /* AmigaCommand: one '.MOD' file command. Patterns are composed of such commands. */
  40.  
  41. typedef struct AmigaCommand {
  42.     unsigned int InstrHiNibble : 4;    /* Number of instrument (hi nibble) */
  43.     unsigned int AmigaPeriod : 12;    /* Output frequency = 3.579545 MHz / AmigaPeriod */
  44.     unsigned int InstrLoNibble : 4;    /* Number of inst. (lo nibble), 0 => no change */
  45.     unsigned int EffectCmd : 4;    /* Effects: Command */
  46.     unsigned int EffectArg : 8;        /*            and operand */
  47. } AmigaCommand, *AmigaCommandPtr;
  48.  
  49. /* How the commands are interpreted: */
  50. /* (…to be translated) */
  51.  
  52. /*
  53.  * (1) Vorab:
  54.  *    (a)    Die folgende Routine wird i. a. alle 20 ms (50 Hz) durchgeführt,
  55.  *        beim Amiga ursprünglich im VBL-Interrupt (Name wird hier verwendet).
  56.  *        Kann durch STCMD_ADJUST_SPEED feinjustiert werden (9.8ms bis 78 ms).
  57.  *    (b)    Sie wird für jede Stimme unabhängig durchgeführt, daher wird im folgenden
  58.  *        nur eine Stimme betrachtet.
  59.  * (2) Alle 20 ms:
  60.  *    (a)    Die Aufruf-Frequenz wird zunächst geteilt durch ws_divisor.
  61.  *        Der Wert von ws_divisor wird durch STCMD_SET_SPEED gesetzt, Default ist 6.
  62.  *    (b)    Alle ws_divisor wird ein NEUES Kommando geholt, gespeichert für (c)
  63.  *        und gemäß (3) interpretiert.
  64.  *        Hier wird das InstrLo/HiNibble und AmigaPeriod ausgewertet,
  65.  *        sowie der unmittelbare Effekt (EffectCmd) (nur manche Effekte werden
  66.  *        unmittelbar ausgeführt).
  67.  *    (c)    In allen anderen Aufrufen wird das in (b) gespeicherte EffectCmd
  68.  *        interpretiert (4) (periodischer Effekt).
  69.  *        Der Effekt könnte auch von (b) unmittelbar interpretiert worden sein.
  70.  *        Mit Ausnahme von STCMD_EXTRA wurde dabei jedoch eine andere Routine 
  71.  *        verwendet, z. B. eine zur Übernahme von Parametern für den periodischen
  72.  *        Effekt.
  73.  * (3) Ausführung eines NEUEN Kommandos:
  74.  *        Wird nur alle ws_divisor 20 ms-Schritte aufgerufen.
  75.  *    (a)    Wenn Instrument > 0, dann Instrumentwechsel.
  76.  *        Es wird nur der Inhalt des zugehörigen InstrumentRecords in den VoiceRecord
  77.  *        kopiert, eine Übergabe an die Abspielroutine findet hier NICHT statt.
  78.  *        Dies passiert NUR bei (b).
  79.  *        Das Kopieren ist überflüssig, nötig sind nur
  80.  *        (a1) ein Instrumenten-Index, (a2) Volume / Finetune und (a3) ein Offset-Wert,
  81.  *        der zunächst auf 0 zu setzen ist (für STCMD_SAMPLE_OFFSET).
  82.  *    (b)    Wenn AmigaPeriod > 0, dann übernehmen in masterPeriod und effectivePeriod.
  83.  *        (Ausnahme: wenn EffectCmd = STCMD_PORTAMENTO_TO oder
  84.  *        STCMD_PORT_TO_VOL_SLIDE. Dann wird auch der Ton nicht neu angeschlagen).
  85.  *        Übernehmen bedeutet, daß der Wert zum nächsten Norm-Ton
  86.  *        gerundet wird (anhand einer Tabelle).
  87.  *        Mit Hilfe des Fine-Tune-Wertes wird der Norm-Ton dann modifiziert.
  88.  *        masterPeriod ist im Normalfall identisch mit dem für die Ausgabe
  89.  *        verwendeten Wert, Ausnahmen sind Effekte wie Vibrato oder Arpeggio.
  90.  *        masterPeriod wird durch die Portamento-Effekte verändert.
  91.  *        Es wird NICHT verändert durch Effekte wie Vibrato oder Arpeggio. Die
  92.  *        verwenden masterPeriod als Ausgangspunkt für ihren Effekt.
  93.  *        Nach der Übernahme wird der Ton neu angeschlagen, d. h.
  94.  *        HIER werden die Sample-Pointer aus den VoiceRecords (evtl. durch (a) gesetzt)
  95.  *        an die Abspielroutine übergeben.
  96.  *        Eigentlich können die Sample-Pointer hier direkt aus den InstrumentRecords
  97.  *        entnommen werden, sofern der Sample-Offset (STCMD_SAMPLE_OFFSET)
  98.  *        separat gespeichert hier mit eingerechnet wird.
  99.  *    (c)    Ausführung unmittelbarer Effekte durch Aufruf entsprechender Routine.
  100.  *        Bei STCMD_EXTRA ist die identisch mit der für den periodischen Effekt.
  101.  * (4) Ausführung des periodischen Effekts:
  102.  *        Wird in jeden 20 ms-Schritt aufgerufen mit Ausnahme jeden ws_divisor-ten.
  103.  *    (a)    Der Effekt wird durch Aufruf der entsprechenden Routine ausgeführt.
  104.  *        Bei STCMD_EXTRA ist die identisch mit der für den unmittelbaren Effekt.
  105.  */
  106.  
  107. /* Available effect commands: */
  108.  
  109. #define STCMD_ARPEGGIO 0
  110. #define STCMD_PORTAMENTO_UP 1
  111. #define STCMD_PORTAMENTO_DOWN 2
  112. #define STCMD_PORTAMENTO_TO 3        /* Portamento with specified destination */
  113. /*        The destination note is specified in AmigaPeriod. When the command */
  114. /*        contains this effect, the note is NOT played again from start, as it would */
  115. /*        usually be for all other effects when AmigaPeriod is > 0. */
  116. #define STCMD_VIBRATO 4
  117. #define STCMD_PORT_TO_VOL_SLIDE 5    /* Portamento with destination */
  118. #define STCMD_VIBRATO_VOL_SLIDE 6
  119. #define STCMD_TREMOLO 7
  120. #define STCMD_UNUSED 8            /* ("KarPlusStrong" = TP [0.5 0.5] on samples) */
  121. #define STCMD_SAMPLE_OFFSET 9    /* Start current inst. sample at offset > 0 */
  122. /*        The starting point of the instrument sample to be used is specified as */
  123. /*        multiples of 256, the offset will be set to (256 * effectArg). */
  124. /*        Achtung: im ProTracker wird der Startpunkt bei jedem Aufruf ERHÖHT, */
  125. /*        was jedoch z. B. bei SPACE DEBRIS dazu führt, daß ein Instrument fast */
  126. /*        nicht mehr zu hören ist. Ein absolutes Setzen klingt so, als ob es so sein soll. */
  127. #define STCMD_VOLUME_SLIDE 10
  128. #define STCMD_POSITION_JUMP 11    /* Go to new song position, pattern from start */
  129. #define STCMD_VOLUME_CHANGE 12    /* Set volume (effectArg 0…64) */
  130. #define STCMD_PATTERN_BREAK 13    /* Immediately end pattern, start next */
  131. #define STCMD_EXTRA 14            /* Extra commands */
  132. /*        Hi nibble of effectArg is code of extra command (EXTRA_xxx, see below) */
  133. #define STCMD_SET_SPEED 15        /* Set 50 Hz divisor (effectArg = 0…31) */
  134. /*        A SoundTracker pattern line is interpreted all (effectArg) VBL interrupts. */
  135. /*        Default value is 6, resulting in 8.3 Hz resolution */
  136. #define STCMD_ADJUST_SPEED 15    /* Fine tuning of VBL irq freq. (effectArg = 32…255) */
  137. /*        New VBL irq period = 20 ms *125 /EffectArg (Default is 125 => 20 ms, 50 Hz) */
  138.  
  139. #define EXTRA_FILTER 0            /* Switch Amiga sound filter on/off (obsolete) */
  140. #define EXTRA_FINE_PORT_UP 1
  141. #define EXTRA_FINE_PORT_DOWN 2
  142. #define EXTRA_GLISS_CONTROL 3
  143. #define EXTRA_VIBRATO_CONTROL 4
  144. #define EXTRA_FINE_TUNE 5
  145. #define EXTRA_LOOP 6
  146. #define EXTRA_TREMOLO_CONTROL 7
  147. #define EXTRA_UNUSED 8
  148. #define EXTRA_RETRIGGER_NOTE 9
  149. #define EXTRA_VOLUME_UP 10
  150. #define EXTRA_VOLUME_DOWN 11
  151. #define EXTRA_NOTE_CUT 12
  152. #define EXTRA_NOTE_DELAY 13
  153. #define EXTRA_PATTERN_DELAY 14
  154. #define EXTRA_UNUSED2 15
  155.  
  156. /* AmigaPattern: structure of one pattern in the '.MOD' file */
  157.  
  158. typedef struct AmigaPattern {
  159.     AmigaCommand commands[STDPATLENGTH][AMIGAVOICES];    /* 1024 bytes */
  160. } AmigaPattern;
  161.  
  162. /* The file format itself (don't use this structure, for documentation only) */
  163.  
  164. struct SoundTrackSpec {
  165.     char NameSignature[20];        /* Song name (may be different from file name) */
  166. #define OFFSETINSTR 20            /* Instrument descriptors starting here */
  167.     struct FileInstrData fid[31];    /* Inst. descriptors (31 or 15) */
  168.     Byte numPointers;                /* 0x3b6 / 0x1d6: number of pointers USED */
  169.     Byte maxPointers;                /* 0x3b7 / 0x1d7; this value is of no value */
  170.     Byte oPointers[MAXPTRS];        /* 0x3b8 / 0x1d8: pointer list (always 128 bytes) */
  171.     long longFmtSignature;        /* 0x438 /   -   : 31 inst. signature ('M.K.' or 'FLT4') */
  172.     struct AmigaPattern patterns[];    /* 0x43c / 0x258: the patterns follow here */
  173. /*    Sample0[];                        /* Sample data begin after last pattern */
  174. };
  175.  
  176. /***** Macintosh extended '.MOD' format (proprietary): *****/
  177.  
  178. /* Warning: the format specification has not yet been finished and may change. */
  179.  
  180. /* CommandRecord: command record used by V2.0 patterns */
  181.  
  182. typedef struct CommandRecord {
  183. /*    long actionLong;                /* $00: 0 => Command is NOP */
  184.     int instrument;                    /* $00: > 0 => set new instrument */
  185.     Byte noteCmd;                    /* $02: > 0 => set new note (contains NOTE_xxx) */
  186.     Byte effectCmd;                /* $03: > 0 => apply effect (contains EFF_xxx) */
  187.     Byte noteValue;                /* $04: Note value for NOTE_xxx (as MIDI value) */
  188.     Byte effectArg;                /* $05: Argument value for effectCmd */
  189.     unsigned int extraArg;            /* $06: Extra argument (currently unused) */
  190. } CommandRecord, *CommandPtr;
  191.  
  192. #define cmd_actionLong 0
  193. #define cmd_instrument 0
  194. #define cmd_noteCmd 2
  195. #define cmd_effectCmd 3
  196. #define cmd_noteValue 4
  197. #define cmd_effectArg 5
  198. #define cmd_extraArg 6
  199. #define cmd_SIZEOF 8
  200.  
  201. enum {
  202.     NOTE_IDLE,                        /* Don't change the note (0) */
  203.     NOTE_ON,                        /* Note on (additionally) */
  204.     NOTE_OFF,                        /* Switch additional note off */
  205.     NOTE_SET,                        /* Release previous, attack new note */
  206.     NOTE_HARD_SET,                /* Switch off previous, attack new note ('.MOD') */
  207.     NOTE_PORTAMENTO_TO,        /* Special for EFF_PORTAMENTO_TO */
  208.     NOTE_LAST    
  209. };
  210.  
  211. #define MIDI_FIRST_ST 48            /* First MIDI note used in '.MOD' files */
  212. #define MIDI_LAST_ST 83            /* Laest MIDI note used in '.MOD' files */
  213. #define MIDI_NUM 128                /* Number of MIDI notes (including 0 as a dummy) */
  214.  
  215. /* …to be translated: */
  216.  
  217. /* Besser: zwei Gruppen von Kommandos */
  218. /*    (1)    STYLE_ => Stil des Anschlags der Noten (Portamento, Arpeggio etc.) */
  219. /*    (2)    CONTROL_ => Lautstärke, Stereo, Pattern-Break etc. */
  220.  
  221. enum {
  222.     EFF_IDLE,                        /* Nix tun (0) */
  223.     EFF_ARPEGGIO,
  224.     EFF_ARPEGGIO_SYM,
  225.     EFF_ARPEGGIO_SYM2,
  226.     EFF_PORTAMENTO_UP,
  227.     EFF_PORTAMENTO_DOWN,
  228.     EFF_PORTAMENTO_TO,        /* Accompanied by NOTE_PORTAMENTO_TO */
  229.     EFF_VIBRATO,                /* Lo-Nibble: Amplitude, Hi-Nibble: Frequenz */
  230.     EFF_PORT_TO_VOL_SLIDE,    /* Portamento mit Zielangabe */
  231.     EFF_VIBRATO_VOL_SLIDE,
  232.     EFF_TREMOLO,
  233.     EFF_SAMPLE_OFFSET,        /* Aktuelles Instrument nicht am Beginn starten */
  234.     EFF_VOLUME_STEP,        /* Einen Schritt in der Lautstärke */
  235.     EFF_VOLUME_SLIDE,        /* Pro VBL einen Schritt in der Lautstärke */
  236.     EFF_NOTE_STEP,            /* Einen Schritt in der Note (hoch oder runter) */
  237.     EFF_NOTE_SLIDE,            /* Pro VBL einen solchen Schritt */
  238.     EFF_POSITION_JUMP,        /* neue Song-Position, Pattern von vorne */
  239.     EFF_VOLUME_CHANGE,        /* (Argument 0..64) */
  240.     EFF_STEREO_CHANGE,        /* (Argument 128..255) */
  241.     EFF_PATTERN_BREAK,        /* Pattern beenden */
  242.     EFF_SET_VBL_DIVISOR,    /* (Argument 0..31) */
  243.     EFF_SET_VBL_ADJUST,    /* (Argument 32..255) */
  244.     EFF_FINE_PORT_UP,
  245.     EFF_FINE_PORT_DOWN,
  246.     EFF_GLISS_TYPE,
  247.     EFF_VIBRATO_TYPE,        /* Vibrato-Typ VIBRATO_TYPE_SINE oder _RAMP */
  248.     EFF_FINE_TUNE,
  249.     EFF_FOR,
  250.     EFF_NEXT,
  251.     EFF_TREMOLO_TYPE,
  252.     EFF_RETRIGGER_NOTE,
  253.     EFF_NOTE_CUT,
  254.     EFF_NOTE_DELAY,
  255.     EFF_DELAY,                    /* Um effectArg Noten verzögern */
  256.     EFF_END,                    /* Ende des Stückes */
  257.     EFF_LAST
  258. };
  259.  
  260. /* EFF_VIBRATO_TYPE: wie wird Periode bei Vibrato moduliert ? */
  261. #define VIBRATO_TYPE_SINE 0            /* Sinus */
  262. #define VIBRATO_TYPE_RAMP_DOWN 1    /* steigende Rampe (-1…+1) (falld. für Freq.) */
  263. #define VIBRATO_TYPE_RAMP_UP 4        /* fallende Rampe (+1…-1) (Rampen ungerade) */
  264. #define VIBRATO_TYPE_RECT 2            /* Rechteck (+1, -1) */
  265. #define VIBRATO_TYPE_RECT2 3            /* (Mehrdeutigkeit im ProTr.: auch Rechteck) */
  266. #define VIBRATO_TYPE_TRI 5                /* symmetrisches Dreieck */
  267. #define VIBRATO_KEEP_PHASE 0x80        /* Bei Anschlag Phase NICHT zurücksetzen! */
  268.  
  269. /***** Data structures for internal representation of song file: *****/
  270.  
  271. #define POSITION_LEFT 0
  272. #define POSITION_CENTER 32
  273. #define POSITION_RIGHT 64
  274. #define POSITION_SURROUND 96
  275. #define POSITION_DEFAULT 0xff
  276. #define POSITION_NO_CHANGE 0xfe
  277.  
  278. #define VOLUME_DEFAULT 0xff
  279. #define VOLUME_NO_CHANGE 0xfe
  280.  
  281. /* Constants for values that may be stored in the speed field: */
  282. /* Warning: the SoundTracker playing mechanism represents a finite state machine. */
  283. /* The execution of finite state machines can not be reversed in any cases, so */
  284. /* playing a song backwards may result in wrong settings of VBLDivisor, */
  285. /* VBLAdjust and playingTime. Furthermore, jumps in the song can not be reversed. */
  286. #define SPEED_NORMAL 1                    /* Normal playing speed */
  287. #define SPEED_HOLD 0                        /* Hold the music (different from pause) */
  288. #define SPEED_BACKWARDS -1            /* May not work in any cases! */
  289. #define SPEED_FASTFORWARD 2            /* Fast forward: values > 1 */
  290. #define SPEED_FASTERFORWARD 4
  291. #define SPEED_EVENFASTERFORWARD 8
  292. #define SPEED_REWIND -2                    /* Rewind: values < -1 */
  293. #define SPEED_FASTERREWIND -4
  294. #define SPEED_EVENFASTERREWIND -8
  295.  
  296. /* Workspace: variables used when playing back a song */
  297.  
  298. typedef struct Workspace {
  299.     signed char speed;                /* $00: Soviele Ticks aufeinmal (Spulen; 1 = normal) */
  300.     Byte ffCounter;                /* $01: Zähler dafür */
  301.  
  302.     unsigned int VBLFrames;        /* $02: soviele Bytes pro VBL-Tick */
  303.     Byte VBLDivisor;                /* $04: VBL-Teiler, Default = 6 */
  304.  
  305.     Byte songPos;                    /* $05: Byte ? */
  306.     int pattPos;                    /* $06: aktuelle Pattern-Position (Zeilenindex) */
  307.  
  308.     Byte cycle;                        /* $08: "VBL"-Zähler */
  309.  
  310.     Boolean pattBreak;                /* $09: Break-Flag für Patterns */
  311.  
  312.     Boolean loopDetect;            /* $0a: Loop-Erkennung ? */
  313.     Boolean looping;                /* $0b: Loop wurde erkannt */
  314.  
  315.     Boolean endOfSong;            /* $0c: Ende des Stückes (keine neuen Noten mehr) */
  316.     Boolean nextOne;                /* $0d: Ende oder Loop; nächstes Stück nehmen */
  317.  
  318.     int speedFactor;                /* $0e: Externer Faktor vom User-Interface (in %) */
  319.     unsigned int VBLAdjust;        /* $10: ProTrkr. 2.0-VBL-Adjust 32/125 … 255/155 ≈ 0.256 … 2.04 */
  320.                                     /*        VBLAdjust = BPM für VBLDivisor = 6 !! */
  321.  
  322.     int overwriteVoice;            /* $12: Echtzeit-Overwrite dieses Kanals */
  323.     CommandRecord overwriteCommand;    /* $14: Overwrite dieses Kommandos (0 = inaktiv) */
  324.  
  325.     Fixed playingTime;                /* $1c: Spielzeit in Sekunden */
  326.  
  327.     Fixed prevHardFreq;            /* $20: auf dieser hardFreq basieren aktuelle Rates */
  328.     
  329.     int ** periodTable;                /* $24: Handle auf Amiga-Perioden der MIDI-Töne */
  330.     Byte delay;                        /* $28: Delay-Counter */
  331.     Byte patternStart;                /* $29: EFF_PATTERN_BREAK mit Pos. > 0 */
  332.  
  333.     Byte reserved2[16]    ;            /* $2a */
  334.  
  335.     int numVoices;                    /* $3a: Anzahl Stimmen (Anzahl Voice-Records) */
  336.     Handle voices;                    /* $3c: Handle auf Voice-Records */
  337.     
  338.     Boolean hold;                    /* $40: Sample nicht updaten (internes Flag) */
  339.     Byte prevSongPos;                /* $41: vorige Song-Position */
  340.     int prevPattPos;                /* $42: vorige Pattern-Position */
  341.     
  342.     Fixed requestedPlayingTime;    /* $44: Jump to value stored here (WO) */
  343.     
  344.     Byte reserved[0x8c];            /* $48 */
  345. } WorkspaceRecord, *WorkspacePtr;
  346.  
  347. #define ws_speed 0x00
  348. #define ws_ffCounter 0x01
  349. #define ws_VBLFrames 0x02
  350. #define ws_VBLDivisor 0x04
  351. #define ws_songPos 0x05
  352. #define ws_pattPos 0x06
  353. #define ws_cycle 0x08
  354. #define ws_pattBreak 0x09
  355. #define ws_loopDetect 0x0a
  356. #define ws_looping 0x0b
  357. #define ws_endOfSong 0x0c
  358. #define ws_nextOne 0x0d
  359. #define ws_speedFactor 0x0e
  360. #define ws_VBLAdjust 0x10
  361. #define ws_overwriteVoice 0x12
  362. #define ws_overwriteCommand 0x14
  363. #define ws_playingTime 0x1c
  364. #define ws_prevHardFreq 0x20
  365. #define ws_periodTable 0x24
  366. #define ws_delay 0x28
  367. #define ws_patternStart 0x29
  368. #define ws_numVoices 0x3a
  369. #define ws_voices 0x3c
  370. #define ws_hold 0x40
  371. #define ws_prevSongPos 0x41
  372. #define ws_prevPattPos 0x42
  373. #define ws_requestedPlayingTime 0x44
  374. #define ws_reserved 0x48
  375. #define ws_SIZEOF 0xd4
  376.  
  377. /* InstrumentRecord: internal representation of an instrument */
  378.  
  379. typedef struct InstrumentRecord {        /* Don't use, will change */
  380. /* …später: Instrument-Sharing (sinnvoll, da Instrumente viel Platz brauchen) */
  381. /*    int numRefs;            /* $xx: so oft wird dieses Instrument verwendet */
  382. /*    int locks;                /* $xx: so oft gelockt (nur HUnlock, wenn locks = 0) */
  383.  
  384. /*    …ganze Ranges angeben! Z.B. Array */
  385. /*    Byte note;                /* $xx: dieser Ton ist gespeichert (MIDI-Angabe) */
  386. /*    Fixed sampleFreq;        /* $xx: Original-Samplefrequenz */
  387.  
  388.     Handle sample;            /* $00: Zeiger auf 1. Sample …wird Offset in dieses Handle */
  389.  
  390.     /* Die folgenden Angaben enthalten 2^ldOverSampling als Faktor: */
  391.     unsigned long length;    /* $04: Offset hinter letztes Originalsample */
  392.     unsigned long loopStart;    /* $08: hier beginnt Loop (z.Zt. length-loopLength) */
  393.     unsigned long loopLength;    /* $0c: Distanz vom Ende zum Loop-Beginn */
  394.     
  395.     /* Zusatzinfo: */
  396.     Byte initialVolume;    /* $10: Default-Lautstärke 0…64 (Übern. bei Inst.-Wechsel) */
  397.     Byte instrumentStPos;    /* $11: Stereo-Position (Default des Instruments) */
  398.     Byte ldOverSampling;    /* $12:    Wieoft Frequenz shiften (0..3) ? */
  399.     Byte initialFineTune;    /* $13:    Frequenzjustage */
  400.     Byte reserved[28];
  401.     
  402.     /* Name: */
  403.     Str63 name;            /* $30: Name des Instruments */
  404. } InstrumentRecord, *InstrumentPtr;
  405.  
  406. #define ins_sample 0x00
  407. #define ins_length 0x04
  408. #define ins_loopStart 0x08
  409. #define ins_loopLength 0x0c
  410. #define ins_initialVolume 0x10
  411. #define ins_instrumentStPos 0x11
  412. #define ins_ldOverSampling 0x12
  413. #define ins_initialFineTune 0x13
  414. #define ins_name 0x30
  415. #define ins_SIZEOF 0x70
  416.  
  417. /* TimeTrackRecord: extra track for timing information (currently not used) */
  418.  
  419. typedef struct TimeTrackRecord {        /* Specifies duration of pattern line */
  420.     unsigned int stepNumer;            /* $00: Numerator (0 => next line immediately) */
  421.     unsigned int stepDenom;            /* $02: Denominator */
  422. } TimeTrackRecord, * TimeTrackPtr, ** TimeTrackHandle;
  423.  
  424. #define tt_stepNumer 0
  425. #define tt_stepDenom 2
  426. #define tt_SIZEOF 4
  427.  
  428. /* PatternRecord: a pattern in memory */
  429.  
  430. #define MAXTRACKS 32
  431.  
  432. typedef struct PatternRecord {
  433.     unsigned int commandsOffset;        /* $00: offset to commands */
  434.     int res1;                            /* $02 */
  435.     
  436.     /* References: */
  437.     unsigned int songRefs;                /* $04: How often used in song ? */
  438.     unsigned int spareRefs;            /* $06: How often used in spare ? */
  439.     unsigned int undoRefs;                /* $08: How often used in undo buffer ? */
  440.     unsigned int clipBoardRefs;        /* $0a: How often used in clipboard ? */
  441.     long res2;                            /* $0c */
  442.     
  443.     /* Pattern dimensions: can be changed with ReshapePattern() */
  444.     /* (actually, ReshapePattern() never decreases any dimension) */
  445.     unsigned int numTracks;            /* $10: number of active tracks */
  446.     unsigned int length;                /* $12: number of active lines */
  447.     unsigned int width;                /* $14: width of array (≥ numVoices) */
  448.     unsigned int height;                /* $16: height of array (≥ length) */
  449.     unsigned int rowBytes;                /* $18: length of line in bytes (for player) */
  450.     Byte res3[6];                        /* $1a */
  451.     
  452.     /* More info: */
  453.     Str255 name;                        /* $20: Pattern name */
  454.     Byte localKey;                        /* $120: key (-1: use globalKey) */
  455.     Byte res4;                            /* $121 */
  456.     Byte patternDefStPos[MAXTRACKS];    /* $122: Default stereo positions */
  457.     int res5;                            /* $142 */
  458.     
  459.     /* Time-Track: */
  460.     TimeTrackHandle timeTrack;        /* $144 */
  461.     
  462.     /* Contents of pattern: */
  463.     /* Warning: always access via commandOffset (see above), so more fields */
  464.     /* can be inserted in PatternRecord! */
  465.     CommandRecord commands[];        /* $148: Command array */
  466. } PatternRecord, *PatternPtr, **PatternHandle;
  467.  
  468. typedef PatternHandle ** PatternListHandle;    /* Handle to array of PatternHandles */
  469.  
  470. #define pat_commandsOffset 0x00
  471. #define pat_songRefs 0x04
  472. #define pat_spareRefs 0x06
  473. #define pat_undoRefs 0x08
  474. #define pat_clipBoardRefs 0x0a
  475. #define pat_numTracks 0x10
  476. #define pat_length 0x12
  477. #define pat_width 0x14
  478. #define pat_height 0x16
  479. #define pat_rowBytes 0x18
  480. #define pat_name 0x20
  481. #define pat_localKey 0x120
  482. #define pat_patternDefStPos 0x122
  483. #define pat_timeTrack 0x144
  484. #define pat_commands 0x148
  485. #define pat_SIZEOF 0x148
  486.  
  487. /* SoundTrack: main data structure and handle to song in memory */
  488.  
  489. /* Commented fields may be accessed directly. However, to access the workspace */
  490. /* and instruments, use corresponding routines to obtain a pointer. This allows */
  491. /* changes in the data structure. */
  492.  
  493. /* This record cannot be shared, a SoundTrack can only be played once at a time! */
  494.  
  495. typedef struct SoundTrack {
  496.     struct PChannel * pchannel;        /* $00: Linked PChannel (NULL => none) */
  497.     char signature[21];                    /* $04: Original '.MOD' song name */
  498.     Byte ldOverSampling;                /* $19: Apply anti-alias filter at load time (RO) */
  499.     Boolean check;                        /* $1a: Is result of structure check, don't play! */
  500.     Byte paddedInstruments;            /* $1b */
  501.     WorkspaceRecord workspace;        /* $1c: Workspace (use routine to get address!) */
  502.  
  503.     Byte numInstruments;                /* $f0: Number of instruments */
  504.     Byte pad1a;                        /* $f1 */
  505.     Byte pad1b;                        /* $f2 */
  506.     
  507.     /* Pointer list: */
  508.     Byte numPointers;                    /* $f3: Number of pointers USED (-> song length) */
  509.     Handle pointers;                    /* $f4: Handle to pattern references */
  510.  
  511.     /* Reference Count: */    
  512.     int refCount;                        /* $f8: Freigabe nur bei refCount = 1 */
  513.  
  514.     /* Patterns: */
  515.     int numPatterns;                    /* $fa: Number of patterns */
  516.     PatternListHandle patterns;        /* $fc: Handle to list of pattern handles */
  517.     
  518.     /* Dateityp ('M.K.', 'PRO ' (mit ProTracker-Eff.), 'FLT4/8', 'OLD ' (15 Stimmen), 'OKTA'): */
  519.     OSType typeID;                        /* $100: Dateityp */
  520.  
  521.     long paddedBytes;                    /* $104 */
  522.     Byte filler[12];
  523.  
  524.     /* Extended song info for editor: */
  525.     Rect windowRect;                    /* $114: 'rect' of edit window (pos, size) */
  526.     Byte globalKey;                    /* $11c: 'KEY_' main key of the song (MIDI-like) */
  527.     Byte initialVBLDivisor;            /* $11d: 'SSPD' Initial VBL divisor */
  528.     unsigned int initialVBLAdjust;        /* $11e: 'SADJ' Initial VBL period */
  529.     Fixed totalPlayingTime;            /* $120: 'TTIM' Total playing time in seconds */
  530.     unsigned int beatsPerMinute;        /* $104: 'BPM_' (ersatzweise aus Songp. 2 geschätzt) */
  531.     Byte res[10];                        /* $126 */
  532.     Str255 title;                        /* $130: 'NAME' Song title */
  533.     Str255 author;                        /* $230: 'AUTH' Author (name / address) */
  534.     Str255 arrangeur;                    /* $330: 'ARRG' Arranger (name / address) */
  535.     Str255 copyright;                    /* $430: '(c) ' Copyright notice */
  536.     Str255 annotation;                    /* $530: 'ANNO' Author's annotation */
  537.     Str255 reservedStr;                /* $630: …wech */
  538.  
  539.     /* Instruments (do NOT access directly, this WILL change)! */
  540.     InstrumentRecord instruments[];    /* $730: Array of InstrumentRecords */
  541. } SoundTrack, * SoundTrackPtr, ** SoundTrackHandle;
  542.  
  543. #define st_pchannel 0x00
  544. #define st_signature 0x04
  545. #define st_ldOverSampling 0x19
  546. #define st_check 0x1a
  547. #define st_paddedInstruments 0x1b
  548. #define st_workspace 0x1c
  549. #define st_numInstruments 0xf0
  550. #define st_numPointers 0xf3
  551. #define st_pointers 0xf4
  552. #define st_refCount 0xf8
  553. #define st_numPatterns 0xfa
  554. #define st_patterns 0xfc
  555. #define st_typeID 0x100
  556. #define st_paddedBytes 0x104
  557. #define st_windowRect 0x114
  558. #define st_globalKey 0x11c
  559. #define st_initialVBLDivisor 0x11d
  560. #define st_initialVBLAdjust 0x11e
  561. #define st_totalPlayingTime 0x120
  562. #define st_beatsPerMinute 0x124
  563. #define st_title 0x130
  564. #define st_author 0x230
  565. #define st_arrangeur 0x330
  566. #define st_copyright 0x430
  567. #define st_annotation 0x530
  568. #define st_instruments 0x730
  569.  
  570. /***** Error codes: *****/
  571.  
  572. #define errBadFormat badMDBErr        /* GetSoundTrack(): wrong or unsupp. file format */
  573.  
  574. /***** Function prototypes: *****/
  575.  
  576. /*** Reading and writing song files: ***/
  577. /* Note: writing NOT implemented yet */
  578.  
  579. extern pascal OSErr GetSoundTrack (int vRefNum, StringPtr fName, Byte ldOverSampling,
  580.                         SoundTrackHandle *soundTrackHandle, Boolean check);
  581. extern pascal OSErr HGetSoundTrack (int vRefNum, long dirID, StringPtr fName, Byte ldOverSampling,
  582.                         SoundTrackHandle *soundTrackHandle, Boolean check);
  583. extern pascal OSErr FSpGetSoundTrack (FSSpecPtr spec, Byte ldOverSampling,
  584.                         SoundTrackHandle *soundTrackHandle, Boolean check);
  585. extern pascal OSErr PutSoundTrack (int vRefNum, StringPtr fName, SoundTrackHandle sth);
  586. extern pascal OSErr HPutSoundTrack (int vRefNum, long dirID, StringPtr fName, SoundTrackHandle sth);
  587. extern pascal OSErr FSpPutSoundTrack (FSSpecPtr spec, SoundTrackHandle sth);
  588.  
  589. /*** Handling song resources: ***/
  590. /* Note: this enables you reading '.MOD' “files” from resources! */
  591.  
  592. extern pascal OSErr GetSoundTrackResource (ResType resType, int resID, Byte ldOverSampling,
  593.                     SoundTrackHandle *soundTrackHandle, Boolean check);
  594. extern pascal OSErr GetNamedSoundTrackResource (ResType resType, StringPtr resName,
  595.                         Byte ldOverSampling, SoundTrackHandle *soundTrackHandle, Boolean check);
  596. extern pascal OSErr AddSoundTrackResource (int resType, int resId, 
  597.                         Boolean extraSndRes, SoundTrackHandle sth);
  598.  
  599. /*** Memory management: ***/
  600.  
  601. extern pascal OSErr NewSoundTrack (int numVoices, int numPatterns, int numInstruments, 
  602.                         SoundTrackHandle *sth);
  603. extern pascal void DisposeSoundTrack (SoundTrackHandle sth);
  604. extern pascal OSErr MoreInstruments (SoundTrackHandle sth, int numInstruments);
  605. extern pascal OSErr MoreVoices (SoundTrackHandle sth, int numVoices);
  606. extern pascal OSErr MorePatterns (SoundTrackHandle sth, int numPatterns);
  607. extern pascal OSErr ReshapePattern (SoundTrackHandle sth, int index, int newTracks, int newLength);
  608.  
  609. /*** Interfacing the playing routines: ***/
  610.  
  611. extern pascal struct SoundTrack * LockSoundTrack (SoundTrackHandle soundTrack);
  612. extern pascal void UnlockSoundTrack (SoundTrackHandle soundTrack);
  613.  
  614. extern pascal void LinkSoundTrack (SoundTrackHandle soundTrack, struct PChannel * pc);
  615. extern pascal void UnlinkSoundTrack (SoundTrackHandle soundTrack);
  616. extern pascal void UpdateSoundTrack (SoundTrackHandle soundTrack);
  617.  
  618. /*** Data structure access: ***/
  619.  
  620. extern pascal InstrumentPtr GetSoundTrackInstrument (SoundTrackHandle sth, int i);
  621. extern pascal WorkspacePtr GetSoundTrackWorkspace (SoundTrackHandle sth);
  622. extern pascal PatternHandle GetSoundTrackPattern (SoundTrackHandle sth, int i);
  623.  
  624. /*** Other routines: ***/
  625.  
  626. extern pascal OSErr RecalcSoundTrack (SoundTrackHandle sth);
  627. extern pascal void SetSoundTrackStereoPosition (SoundTrackHandle sth, int i, Byte pos);
  628. extern pascal int VersionSoundTrack();
  629. extern pascal void CopyrightSoundTrack (StringPtr s);
  630.  
  631. #endif
  632.